//
//  MPBModelSupport.h
//  基本工具类的封装
//  MPBModelType：封装运行时属性的类型
//  MPBModelProperty：运行时属性的封装
//
//


#import <Foundation/Foundation.h>
#import <objc/runtime.h>


/// 全局属性编码参数
/// Int 类型
extern NSString *const LKTypeInt;

/// float 类型
extern NSString *const LKTypeFloat;

/// double 类型
extern NSString *const LKTypeDouble;

/// long 类型
extern NSString *const LKTypeLong;

/// long long 类型
extern NSString *const LKTypeLongLong;

/// char 类型
extern NSString *const LKTypeChar;

/// bool 类型（用不到）
extern NSString *const LKTypeBOOL;

/// pointer 类型
extern NSString *const LKTypePointer;

/// ivar 类型
extern NSString *const LKTypeIvar;

/// method 类型
extern NSString *const LKTypeMethod;

/// block 类型
extern NSString *const LKTypeBlock;

/// class 类型
extern NSString *const LKTypeClass;

/// SEL 类型
extern NSString *const LKTypeSEL;

/// id 类型
extern NSString *const LKTypeId;


/*!
 *
 *  @brief  支持类
 *
 */
@interface MPBModelSupport : NSObject

/*!
 *  
 *  @brief  判断是否为框架类型
 *
 *  @param  c 需要判断的类型
 *
 *  @return 是否
 *
 */
+ (BOOL)isClassFromFoundation:(Class)c;

@end


/*!
 *
 *  @brief  运行时属性类型
 *  @  1、保存每个运行时属性的定义类型
 *  @  2、能够实现属性名称更改
 *  @  3、能够实现赋值类型的安全性校验
 */
@interface MPBModelType : NSObject

/// 属性编码
@property (nonatomic, copy) NSString *code;

/// 属性的定义类型，如果是基本数据类型，此值为 nil
@property (nonatomic, readonly) Class typeClass;

/// 是否为id类型
@property (nonatomic, readonly, getter=isIdType) BOOL idType;

/// 是否为基本数字类型
@property (nonatomic, readonly, getter=isNumberType) BOOL numberType;

/// 是否来自系统框架
@property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation;

/// 是否不支持 KVC
@property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled;


/*!
 *
 *  @brief  类方法，创建 type 对象
 *
 *  @param  code 属性编码 @
 *
 *  @return type 对象
 *
 */
+ (instancetype)cachedTypeWithCode:(NSString *)code;

@end


/*!
 *
 *  @brief  封装的运行时属性类型
 *
 */
@interface MPBModelProperty : NSObject

/// 运行时属性
@property (nonatomic, assign) objc_property_t property;

/// 定义的属性名
@property (nonatomic, readonly) NSString *name;

/// 成员变量的类型
@property (nonatomic, readonly) MPBModelType *type;

/// 所属类
@property (nonatomic, assign) Class srcClass;


/*!
 *
 *  @brief  创建并缓存封装的运行时属性
 *
 *  @param  property 需要处理的运行时属性
 *
 *  @return 封装的运行时属性
 *
 */
+ (instancetype)cachedPropertyWithProperty:(objc_property_t)property;

/*!
 *
 *  @brief  对应着字典中的 key
 *
 *  @param  key 字典中的 key
 *  @param  c   对应的类
 *

 */
- (void)setKey:(NSString *)key forClass:(Class)c;

/*!
 *
 *  @brief  类中存放的字典 key
 *
 *  @param  c 对应的类
 *
 *  @return 字典中的 key
 *

 */
- (NSString *)keyFromClass:(Class)c;

/*!
 *
 *  @brief  设置成员变量的值
 *
 *  @param  value  值
 *  @param  object 赋值的对象
 *

 */
- (void)setValue:(id)value forObject:(id)object;

@end

